package com.fingard.dsp.bank.directbank.pab01;

import com.fingard.dsp.bank.directbank.FailCode;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.IBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.detail.RetAtsBatPayRecDetail;
import com.fingard.io.FileHelper;
import com.fingard.net.ConnState;
import com.fingard.text.StringHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.io.BufferedReader;
import java.io.File;
import java.io.StringReader;

/**
 * 平安银行批量代收付
 * <p>
 * 参考文档：
 * 平安银行银企直连接口文档1.0.doc
 * 平安银行银企直连-橙e收款接口V2.5.docx
 *
 * @author Cruise
 * @date 2018/11/08
 */
public class PAB01BatPayRec extends PAB01Base implements IBatPayRec {
    /**
     * 批量代付提交
     * <p>
     * 参考文档：平安银行银企直连接口文档1.0.doc
     * 支持接口：3.4 企业大批量资金划转[4018]
     */
    public RetAtsBatPayRec d_1988_BatPay(ReqBatPayRec p_req1988) throws Exception {
        if ("198803".equals(p_req1988.reqHeader.commandCode)) {
            return dealBatPaySubmit(p_req1988);
        } else {
            return d_BatPayRec(p_req1988);
        }
    }

    public RetAtsBatPayRec dealBatPaySubmit(ReqBatPayRec p_req1988) throws Exception {
        RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_req1988.reqHeader);
        retAts.reqSeqID = p_req1988.reqBatchNO;
        try {
            PAB01Header bankHeader = new PAB01Header();
            bankHeader.trncode = "FILE01";
            bankHeader.fourZero = "0000";
            bankHeader.reqSeqNo = p_req1988.reqHeader.transSeqID;

            StringBuilder sbFileContent = new StringBuilder();
            sbFileContent.append(p_req1988.ownAct).append("|::|");
            sbFileContent.append(p_req1988.totalNum).append("|::|");
            sbFileContent.append(p_req1988.totalAmt);
            while (p_req1988.readRecord()) {
                sbFileContent.append("\r\n");
                sbFileContent.append(p_req1988.readedDetail.askNumber).append("|::|");
                sbFileContent.append(p_req1988.readedDetail.recAct).append("|::|");
                sbFileContent.append(p_req1988.readedDetail.recName).append("|::|");
                String[] location = p_req1988.readedDetail.recAreaName.split("_");
                sbFileContent.append(location[0]).append("|::|");
                sbFileContent.append(location[1]).append("|::|");
                sbFileContent.append(p_req1988.readedDetail.cnapsName).append("|::|");
                sbFileContent.append(p_req1988.readedDetail.payAmount).append("|::|");
                String protocolNo = p_req1988.readedDetail.srcXElement.getSingleText(getBankConfig().getValueAsString("protocolNo"));
                sbFileContent.append(protocolNo).append("|::|");
                sbFileContent.append(p_req1988.readedDetail.cnapsCode).append("|::|");
            }
            String tmpUploadFileName = p_req1988.reqBatchNO + ".txt";
            String tmpLocalMarkPath = getBankConfig().getValueAsString("FTPLocalUploadDir") + File.separator + tmpUploadFileName;
            WriteBankLogLn2("批次文件保存本机路径: " + tmpLocalMarkPath);
            FileHelper.writeFile(tmpLocalMarkPath, sbFileContent.toString(), getCharset());

            XmlTextWriter xmlWriter = new XmlTextWriter();
            xmlWriter.autoFormat = false;
            writeCommonHeader(xmlWriter);

            xmlWriter.writeStartElement("Result");
            xmlWriter.writeElementString("TradeSn", p_req1988.reqBatchNO);
            xmlWriter.writeElementString("FileName", tmpUploadFileName);
            xmlWriter.writeElementString("FilePath", getBankConfig().getValueAsString("FTPUploadDir"));
            xmlWriter.writeEndDocument();
            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString(), bankHeader);
            if (tmpStrRet[0].length() == 0) {
                byte[] retBytes = tmpStrRet[1].getBytes(getCharset());
                String tmpRetCode = new String(retBytes, 87, 6, getCharset()).trim();
                String tmpRetMsg = new String(retBytes, 94, 99, getCharset()).trim();
                if ("000000".equals(tmpRetCode)) {
                    String delayFILE02 = getBankConfig().getValueAsString("useDelayFILE02");
                    if ("true".equals(delayFILE02.toLowerCase())) {
                        long delayFILE02Time = getBankConfig().getValueAsInt("delayFILE02Time");
                        Thread.sleep(delayFILE02Time * 1000);
                    }
                    String randomPwdUp = "";
                    int tmpSleepCount = 0;
                    while (true) {
                        PAB01Header FILE02Header = new PAB01Header();
                        FILE02Header.trncode = "FILE02";
                        FILE02Header.fourZero = "0000";
                        FILE02Header.reqSeqNo = p_req1988.reqHeader.transSeqID;
                        XmlTextWriter FILE02 = new XmlTextWriter();
                        FILE02.autoFormat = false;
                        writeCommonHeader(FILE02);
                        FILE02.writeStartElement("Result");
                        FILE02.writeElementString("TradeSn", p_req1988.reqBatchNO);
                        FILE02.writeEndDocument();
                        String[] FILE02StrRet = sendToBank(FILE02.toXmlString(), FILE02Header);
                        if (FILE02StrRet[0].length() == 0) {
                            retBytes = tmpStrRet[1].getBytes(getCharset());
                            tmpRetCode = new String(retBytes, 87, 6, getCharset()).trim();
                            tmpRetMsg = new String(retBytes, 94, 99, getCharset()).trim();
                            int pollingTime = getBankConfig().getValueAsInt("pollingTime");
                            if ("000000".equals(tmpRetCode)) {
                                FILE02StrRet[1] = FILE02StrRet[1].substring(FILE02StrRet[1].indexOf("<"));
                                StringBuilder tmpSbMsg = new StringBuilder();
                                XmlTextReader tmpBkReader = loadBankRespXmlReader(FILE02StrRet[1], tmpSbMsg);
                                if (tmpBkReader != null) {
                                    String Code = tmpBkReader.getFirstText("/Result/Code");
                                    if ("F0".equals(Code)) {
                                        randomPwdUp = tmpBkReader.getFirstText("/Result/RandomPwd");
                                        break;
                                    } else if (Code.indexOf('E') >= 0) {
                                        retAts.respCode = "0";
                                        retAts.respInfo = tmpBkReader.getFirstText("/Result/Desc");
                                        retAts.transState = "PaymentFailed";
                                        retAts.payInfoCode = Code;
                                        return retAts;
                                    } else {
                                        Thread.sleep(1000);
                                        tmpSleepCount++;
                                    }
                                    if (tmpSleepCount > pollingTime) {
                                        break;
                                    }
                                } else {
                                    retAts.respCode = "-1";
                                    retAts.respInfo = tmpRetMsg;
                                    return retAts;
                                }
                            } else {
                                retAts.respCode = "-1";
                                retAts.respInfo = tmpRetMsg;
                                return retAts;
                            }

                        } else if (FILE02StrRet[0].equals(ConnState.FAIL)) {
                            retAts.respCode = "0";
                            retAts.respInfo = FILE02StrRet[1];
                            retAts.transState = PaymentState.FAIL_Batch;
                            retAts.payInfoCode = FailCode.E9999;
                            return retAts;
                        } else {
                            retAts.respCode = "-1";
                            retAts.respInfo = FILE02StrRet[1];
                            return retAts;
                        }
                    }
                    PAB01Header KHKF01Header = new PAB01Header();
                    KHKF01Header.trncode = "KHKF01";
                    KHKF01Header.fourZero = "0000";
                    KHKF01Header.reqSeqNo = p_req1988.reqHeader.transSeqID;
                    XmlTextWriter KHKF01 = new XmlTextWriter();
                    KHKF01.autoFormat = false;
                    writeCommonHeader(KHKF01);
                    KHKF01.writeStartElement("Result");
                    KHKF01.writeElementString("BatchNo", p_req1988.reqBatchNO);
                    KHKF01.writeElementString("AcctNo", p_req1988.ownAct);
                    KHKF01.writeElementString("BusiType", getBankConfig().getValueAsString("BusiType_1988"));
                    KHKF01.writeElementString("CorpId", getBankConfig().getValueAsString("CorpId"));
                    KHKF01.writeElementString("TotalNum", p_req1988.totalNum);
                    KHKF01.writeElementString("TotalAmount", p_req1988.totalAmt);
                    KHKF01.writeElementString("FileName", tmpUploadFileName);
                    KHKF01.writeElementString("RandomPwd", randomPwdUp);
                    KHKF01.writeEndDocument();
                    String[] KHKF01StrRet = sendToBank(KHKF01.toXmlString(), KHKF01Header);
                    if (KHKF01StrRet[0].length() == 0) {
                        retBytes = KHKF01StrRet[1].getBytes(getCharset());
                        tmpRetCode = new String(retBytes, 87, 6, getCharset());
                        tmpRetMsg = new String(retBytes, 93, 100, getCharset()).trim();
                        tmpRetMsg = StringHelper.trimStart(tmpRetMsg, ":");
                        if ("000000".equals(tmpRetCode)) {
                            StringBuilder tmpSbMsg = new StringBuilder();
                            XmlTextReader tmpBkReader = loadBankRespXmlReader(KHKF01StrRet[1].substring(KHKF01StrRet[1].indexOf("<")), tmpSbMsg);
                            retAts.respCode = "0";
                            retAts.respInfo = "请求成功";
                            retAts.transState = tmpRetCode;
                            retAts.payInfoCode = tmpRetCode;
                            retAts.reqSeqID = tmpBkReader.getFirstText("/Result/BatchNo");
                        } else {
                            retAts.respCode = "-1";
                            retAts.respInfo = tmpRetMsg;
                        }

                    } else if (KHKF01StrRet[0].equals(ConnState.FAIL)) {
                        retAts.respCode = "0";
                        retAts.respInfo = KHKF01StrRet[1];
                        retAts.transState = PaymentState.FAIL_Batch;
                        retAts.payInfoCode = FailCode.E9999;
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = KHKF01StrRet[1];
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpRetMsg;
                }

            } else if (tmpStrRet[0].equals(ConnState.FAIL)) {
                retAts.respCode = "0";
                retAts.respInfo = tmpStrRet[1];
                retAts.transState = PaymentState.FAIL_Batch;
                retAts.payInfoCode = FailCode.E9999;
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = tmpStrRet[1];
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.toString();
            WriteBankLogLn(ex);
        }

        retAts.writeRetToATS();
        return retAts;
    }

    public RetAtsBatPayRec d_BatPayRec(ReqBatPayRec p_req1988) throws Exception {
        RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_req1988.reqHeader);
        retAts.reqSeqID = p_req1988.reqBatchNO;

        try {
            PAB01Header bankHeader = new PAB01Header();
            bankHeader.trncode = "4018";
            bankHeader.fourZero = "0000";
            bankHeader.reqSeqNo = p_req1988.reqHeader.transSeqID;

            XmlTextWriter xmlWriter = new XmlTextWriter();
            xmlWriter.autoFormat = false;
            writeCommonHeader(xmlWriter);

            xmlWriter.writeStartElement("Result");
            xmlWriter.writeElementString("ThirdVoucher", p_req1988.reqBatchNO);
            xmlWriter.writeElementString("totalCts", p_req1988.totalNum);
            xmlWriter.writeElementString("totalAmt", p_req1988.totalAmt);
            xmlWriter.writeElementString("BatchSummary", "");
            xmlWriter.writeElementString("BSysFlag", "N");
            xmlWriter.writeElementString("CcyCode", convertCurToBank(p_req1988.ownCur));
            xmlWriter.writeElementString("OutAcctNo", p_req1988.ownAct);
            xmlWriter.writeElementString("OutAcctName", p_req1988.ownActName);
            xmlWriter.writeElementString("OutAcctAddr", "");
            xmlWriter.writeElementString("PayType", "0");
            xmlWriter.writeElementString("BizFlag1", "");

            while (p_req1988.readRecord()) {
                XElement tmpXElement = new XElement("HOResultSet4018R", "");
                tmpXElement.addChild(new XElement("SThirdVoucher", p_req1988.readedDetail.askNumber));
                tmpXElement.addChild(new XElement("CstInnerFlowNo", ""));
                tmpXElement.addChild(new XElement("InAcctBankNode", p_req1988.readedDetail.cnapsCode));
                tmpXElement.addChild(new XElement("InAcctRecCode", p_req1988.readedDetail.cnapsCode));
                tmpXElement.addChild(new XElement("InAcctNo", p_req1988.readedDetail.recAct));
                tmpXElement.addChild(new XElement("InAcctName", p_req1988.readedDetail.recName));
                tmpXElement.addChild(new XElement("InAcctBankName", p_req1988.readedDetail.recBankLocation));
                tmpXElement.addChild(new XElement("InAcctProvinceCode", p_req1988.readedDetail.getOppProvinceAndCity2()[0]));
                tmpXElement.addChild(new XElement("InAcctCityName", p_req1988.readedDetail.getOppProvinceAndCity2()[1]));
                tmpXElement.addChild(new XElement("TranAmount", p_req1988.readedDetail.payAmount));
                tmpXElement.addChild(new XElement("UseEx", p_req1988.readedDetail.purpose));
                tmpXElement.addChild(new XElement("UnionFlag", p_req1988.readedDetail.sameBnk));
                tmpXElement.addChild(new XElement("AddrFlag", p_req1988.readedDetail.sameCity));

                nodeAnalysis(p_req1988.readedDetail.srcXElement, tmpXElement, getCharset());

                xmlWriter.writeXElement(tmpXElement);

            }
            xmlWriter.writeEndDocument();

            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString(), bankHeader);

            if (tmpStrRet[0].length() == 0) {
                byte[] retBytes = tmpStrRet[1].getBytes(getCharset());
                String tmpRetCode = new String(retBytes, 87, 6, getCharset());
                String tmpRetMsg = new String(retBytes, 94, 100, getCharset()).trim();
                tmpStrRet[1] = tmpStrRet[1].substring(tmpStrRet[1].indexOf("<"));

                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    retAts.respCode = "0";
                    retAts.respInfo = tmpRetMsg;
                    retAts.transState = tmpRetCode;
                    retAts.payInfoCode = tmpRetCode;
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpSbMsg.toString();
                }
            } else if (tmpStrRet[0].equals(ConnState.FAIL)) {
                retAts.respCode = "0";
                retAts.respInfo = tmpStrRet[1];
                retAts.transState = PaymentState.FAIL_Batch;
                retAts.payInfoCode = FailCode.E9999;
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = tmpStrRet[1];
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.toString();
            WriteBankLogLn(ex);
        }

        retAts.writeRetToATS();
        return retAts;
    }

    public RetAtsQryBatPayRec d_1998_QryBatPay(ReqQryBatPayRec p_req1998) throws Exception {
        if ("198803".equals(p_req1998.reqHeader.commandCode)) {
            return QryBatPaySubmit(p_req1998);
        } else {
            return d_QryBatPay(p_req1998);
        }
    }

    /**
     * 批量代付查询
     * <p>
     * 参考文档：平安银行银企直连接口文档1.0.doc
     * 支持接口：3.6 批量转账指令查询[4015]
     */
    public RetAtsQryBatPayRec d_QryBatPay(ReqQryBatPayRec p_req1998) throws Exception {
        RetAtsQryBatPayRec retAts = new RetAtsQryBatPayRec(p_req1998.reqHeader);
        retAts.reqSeqID = p_req1998.reqBatchNO;

        try {
            PAB01Header bankHeader = new PAB01Header();
            bankHeader.trncode = "4015";
            bankHeader.fourZero = "0000";
            bankHeader.reqSeqNo = p_req1998.reqHeader.transSeqID;

            boolean hasNext = true;
            String pageNo = "1";
            while (hasNext) {
                XmlTextWriter xmlWriter = new XmlTextWriter();
                xmlWriter.autoFormat = false;
                writeCommonHeader(xmlWriter);
                xmlWriter.writeStartElement("Result");
                xmlWriter.writeElementString("OrigThirdVoucher", p_req1998.reqBatchNO);
                xmlWriter.writeElementString("PageNo", pageNo);
                xmlWriter.writeEndDocument();

                String[] tmpStrRet = sendToBank(xmlWriter.toXmlString(), bankHeader);

                if (tmpStrRet[0].length() == 0) {
                    byte[] retBytes = tmpStrRet[1].getBytes(getCharset());
                    String tmpRetCode = new String(retBytes, 87, 6, getCharset()).trim();
                    String tmpRetMsg = new String(retBytes, 94, 99, getCharset()).trim();
                    if ("000000".equals(tmpRetCode)) {
                        tmpStrRet[1] = tmpStrRet[1].substring(tmpStrRet[1].indexOf("<"));
                        StringBuilder tmpSbMsg = new StringBuilder();
                        XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                        if (tmpBkReader != null) {
                            String tmpbatchSTT = tmpBkReader.getFirstText("/Result/batchSTT");
                            if ("20".equals(tmpbatchSTT)) { // 20：成功
                                retAts.respCode = "0";
                                retAts.respInfo = tmpRetMsg;

                                String isEnd = tmpBkReader.getFirstText("/Result/IsEnd");
                                if ("N".equals(isEnd)) {
                                    pageNo = String.valueOf(Integer.parseInt(pageNo) + 1);
                                } else {
                                    hasNext = false;
                                }
                                while (tmpBkReader.read("/Result/list")) {
                                    RetAtsBatPayRecDetail tmpRetDetail = new RetAtsBatPayRecDetail();

                                    tmpRetDetail.payAct = tmpBkReader.readedXElement.getSingleText("OutAcctNo");
                                    tmpRetDetail.recAct = tmpBkReader.readedXElement.getSingleText("InAcctNo");
                                    tmpRetDetail.recName = tmpBkReader.readedXElement.getSingleText("InAcctName");
                                    tmpRetDetail.payAmount = tmpBkReader.readedXElement.getSingleText("TranAmount");
                                    tmpRetDetail.curType = convertCurToATS(tmpBkReader.readedXElement.getSingleText("CcyCode"));
                                    tmpRetDetail.postScript = tmpBkReader.readedXElement.getSingleText("SThirdVoucher");
                                    tmpRetDetail.result = StringHelper.joinNotEmpty("+", tmpbatchSTT, tmpBkReader.readedXElement.getSingleText("Stt"));

                                    // Yhcljg字段银行必返，无需增加判断
                                    String[] tmpPayInfo = tmpBkReader.readedXElement.getSingleText("Yhcljg").split(":");
                                    tmpRetDetail.payInfoCode = tmpPayInfo[0];
                                    tmpRetDetail.memo = tmpPayInfo[1];

                                    retAts.writeRetDetail(tmpRetDetail);
                                }
                            } else if ("30".equals(tmpbatchSTT)) { // 30：失败
                                retAts.respCode = "0";
                                retAts.respInfo = tmpRetMsg;

                                String tmpbatchInfo = tmpBkReader.getFirstText("/Result/batchSttDesc");
                                if (StringHelper.hasAnyChar(tmpbatchInfo)) {
                                    retAts.respInfo = tmpbatchInfo;
                                    retAts.payInfoCode = tmpbatchInfo;
                                }
                                retAts.transState = StringHelper.joinNotEmpty("+", tmpRetCode, tmpbatchSTT);
                            } else { // 其他为银行受理成功处理中
                                retAts.respCode = "-1";
                                retAts.respInfo = tmpRetMsg;
                                hasNext = false;
                            }
                        } else {
                            retAts.respCode = "-1";
                            retAts.respInfo = tmpSbMsg.toString();
                            hasNext = false;
                        }
                    } else {
                        // 超过30分钟没结果,则判定支付失败
                        if ("YQ9996".equals(tmpRetCode)) {
                            if (!canBeNotExist(p_req1998, retAts, 30)) {
                                retAts.writeAfterDetail();
                                return retAts;
                            }

                            retAts.respCode = "0";
                            retAts.respInfo = tmpRetMsg;
                            retAts.transState = tmpRetCode;
                            retAts.payInfoCode = tmpRetCode;
                        }

                        retAts.respCode = "-1";
                        retAts.respInfo = tmpRetMsg;
                        hasNext = false;
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpStrRet[1];
                    hasNext = false;
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        retAts.writeAfterDetail();
        return retAts;
    }

    public RetAtsQryBatPayRec QryBatPaySubmit(ReqQryBatPayRec p_req1998) throws Exception {
        RetAtsQryBatPayRec retAts = new RetAtsQryBatPayRec(p_req1998.reqHeader);
        retAts.reqSeqID = p_req1998.reqBatchNO;

        try {
            PAB01Header bankHeader = new PAB01Header();
            bankHeader.trncode = "KHKF02";
            bankHeader.fourZero = "0000";
            bankHeader.reqSeqNo = p_req1998.reqHeader.transSeqID;
            XmlTextWriter xmlWriter = new XmlTextWriter();
            xmlWriter.autoFormat = false;
            writeCommonHeader(xmlWriter);

            xmlWriter.writeStartElement("Result");
            xmlWriter.writeElementString("AcctNo", p_req1998.ownAct);
            xmlWriter.writeElementString("BatchNo", p_req1998.reqBatchNO);
            xmlWriter.writeEndDocument();
            String[] KHKF02Ret = sendToBank(xmlWriter.toXmlString(), bankHeader);
            if (KHKF02Ret[0].length() == 0) {
                byte[] retBytes = KHKF02Ret[1].getBytes(getCharset());
                String tmpRetCode = new String(retBytes, 87, 6, getCharset());
                String tmpRetMsg = new String(retBytes, 93, 100, getCharset()).trim();
                tmpRetMsg = StringHelper.trimStart(tmpRetMsg, ":");
                if ("000000".equals(tmpRetCode)) {
                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(KHKF02Ret[1].substring(KHKF02Ret[1].indexOf("<")), tmpSbMsg);
                    if (tmpBkReader != null) {
                        String qryState = tmpBkReader.getFirstText("/Result/BatchStt");
                        if ("20".equals(qryState)) {
                            String fileName = tmpBkReader.getFirstText("/Result/FileName");
                            String fileRandonPwd = tmpBkReader.getFirstText("/Result/RandomPwd");
                            bankHeader = new PAB01Header();
                            bankHeader.trncode = "FILE03";
                            bankHeader.fourZero = "0000";
                            bankHeader.reqSeqNo = getQryTransID();

                            xmlWriter = new XmlTextWriter();
                            xmlWriter.autoFormat = false;
                            xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\"" + getCharset() + "\"?>");
                            xmlWriter.writeStartElement("Result");
                            xmlWriter.writeElementString("TradeSn", p_req1998.reqHeader.transSeqID);
                            xmlWriter.writeElementString("FileName", fileName);
                            xmlWriter.writeElementClosed("FilePath");
                            xmlWriter.writeElementString("RandomPwd", fileRandonPwd);
                            xmlWriter.writeEndDocument();
                            String ftpLocalDir = getBankConfig().getValueAsString("ftpLocalDir");
                            if (StringHelper.isNullOrEmpty(ftpLocalDir)) {
                                retAts.respCode = "-1";
                                retAts.respInfo = "配置文件缺失'ftpLocalDir'节点配置";
                                return retAts;
                            }
                            KHKF02Ret = sendToBank(xmlWriter.toXmlString(), bankHeader);

                            if (KHKF02Ret[0].length() == 0) {
                                retBytes = KHKF02Ret[1].getBytes(getCharset());
                                tmpRetCode = new String(retBytes, 87, 6, getCharset()).trim();
                                tmpRetMsg = new String(retBytes, 94, 99, getCharset()).trim();
                                if ("000000".equals(tmpRetCode)) {
                                    retAts.respCode = "0";
                                    retAts.respInfo = tmpRetMsg;
                                    String localFilePath = StringHelper.trimEnd(ftpLocalDir, File.separator) + File.separator + fileName;
                                    WriteBankLogLn2("本地结果文件路径:" + localFilePath);
                                    if (!new File(localFilePath).exists()) {
                                        retAts.respCode = "-1";
                                        retAts.respInfo = "本地文件不存在";
                                        return retAts;
                                    }
                                    String tmpRetStr = FileHelper.readFileText(localFilePath, getCharset());
                                    WriteBankLogLn2("银行返回的回盘文件内容是:\r\n" + tmpRetStr);

                                    StringReader strReader = new StringReader(tmpRetStr);
                                    BufferedReader tmpReader = new BufferedReader(strReader);

                                    String line = tmpReader.readLine();
                                    while (true) {
                                        String eachline = tmpReader.readLine();
                                        if (eachline == null) {
                                            break;
                                        }
                                        String[] eachNodes = eachline.split("\\|\\:\\:\\|");

                                        RetAtsBatPayRecDetail tmpRetDetail = new RetAtsBatPayRecDetail();
                                        tmpRetDetail.postScript = eachNodes[0];
                                        tmpRetDetail.recAct = eachNodes[1];
                                        tmpRetDetail.payAct = eachNodes[2];
                                        tmpRetDetail.payAmount = eachNodes[3];
                                        tmpRetDetail.result = "KHKF+" + eachNodes[5];
                                        tmpRetDetail.payInfoCode = eachNodes[5];
                                        tmpRetDetail.memo = eachNodes[6].trim();
                                        retAts.writeRetDetail(tmpRetDetail);
                                    }
                                } else {
                                    retAts.respCode = "-1";
                                    retAts.respInfo = tmpRetMsg;
                                }
                            } else {
                                retAts.respCode = "-1";
                                retAts.respInfo = KHKF02Ret[1];
                            }
                        } else if ("30".equals(qryState)) { // 30：失败
                            retAts.respCode = "0";
                            retAts.respInfo = tmpBkReader.getFirstText("/Result/BatchInfo");
                            retAts.payInfoCode = qryState;
                            retAts.transState = qryState;
                        } else {
                            retAts.respCode = "0";
                            retAts.respInfo = tmpBkReader.getFirstText("/Result/BatchInfo");
                        }
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = tmpSbMsg.toString();
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpRetMsg;
                }

            } else if (KHKF02Ret[0].equals(ConnState.FAIL)) {
                retAts.respCode = "0";
                retAts.respInfo = KHKF02Ret[1];
                retAts.transState = PaymentState.FAIL_Batch;
                retAts.payInfoCode = FailCode.E9999;
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = KHKF02Ret[1];
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        retAts.writeAfterDetail();
        return retAts;
    }

    /**
     * 批量代扣提交
     * <p>
     * 参考文档：平安银行银企直连-橙e收款接口V2.5.docx
     * 参考接口：3.5 橙e收款交易接口 [4032]
     * <p>
     * 功能描述：只支持扣借记卡，而且是行内
     */
    public RetAtsBatPayRec d_9188_BatPay(ReqBatPayRec p_req9188) throws Exception {
        RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_req9188.reqHeader);
        retAts.reqSeqID = p_req9188.reqBatchNO;

        try {
            PAB01Header bankHeader = new PAB01Header();
            bankHeader.trncode = "4032";
            bankHeader.fourZero = "0000";
            bankHeader.reqSeqNo = p_req9188.reqHeader.transSeqID;

            XmlTextWriter xmlWriter = new XmlTextWriter();
            xmlWriter.autoFormat = false;
            writeCommonHeader(xmlWriter);

            xmlWriter.writeStartElement("Result");
            xmlWriter.writeElementString("ThirdVoucher", p_req9188.reqBatchNO);
            xmlWriter.writeElementString("AGREE_NO", "");
            xmlWriter.writeElementString("BusiType", "");
            xmlWriter.writeElementString("Currency", "RMB");
            xmlWriter.writeElementString("SrcAccNo", p_req9188.ownAct);
            xmlWriter.writeElementString("TotalNum", p_req9188.totalNum);
            xmlWriter.writeElementString("TotalAmount", p_req9188.totalAmt);
            xmlWriter.writeElementString("SettleType", "1");

            while (p_req9188.readRecord()) {
                XElement tmpXElement = new XElement("HOResultSet4032R", "");
                tmpXElement.addChild(new XElement("SThirdVoucher", p_req9188.readedDetail.askNumber));
                tmpXElement.addChild(new XElement("CstInnerFlowNo", p_req9188.readedDetail.abstractATS));
                tmpXElement.addChild(new XElement("OppAccNo", p_req9188.readedDetail.payAct));
                tmpXElement.addChild(new XElement("OppAccName", p_req9188.readedDetail.payName));
                tmpXElement.addChild(new XElement("OppBank",
                        getBankConfig().getMapValueByKey("bankCodeMapping", p_req9188.readedDetail.payBankCode)));

                String cardType = p_req9188.readedDetail.cardType;
                String isPrivate = p_req9188.readedDetail.isPrivate;
                if (!"1".equals(isPrivate)) {
                    cardType = "2";// 对公账号
                } else {
                    if ("1".equals(cardType)) {
                        cardType = "1";// 存折
                    } else {
                        cardType = "0";// 借记卡
                    }
                }
                tmpXElement.addChild(new XElement("CardAcctFlag", cardType));
                tmpXElement.addChild(new XElement("Amount", p_req9188.readedDetail.payAmount));
                tmpXElement.addChild(new XElement("IdType", convertCertTypeToBank(p_req9188.readedDetail.certType)));
                tmpXElement.addChild(new XElement("IdNo", p_req9188.readedDetail.certNum));
                tmpXElement.addChild(new XElement("Mobile", p_req9188.readedDetail.cellPhone));
                tmpXElement.addChild(new XElement("PostScript", p_req9188.readedDetail.memo));
                xmlWriter.writeXElement(tmpXElement);
            }
            xmlWriter.writeEndElement();

            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString(), bankHeader);

            if (tmpStrRet[0].length() == 0) {
                byte[] retBytes = tmpStrRet[1].getBytes(getCharset());
                String tmpRespCode = new String(retBytes, 87, 6, getCharset()).trim();
                String tmpRespInfo = new String(retBytes, 94, 99, getCharset()).trim();

                retAts.respCode = "0";
                retAts.respInfo = tmpRespInfo;
                retAts.transState = tmpRespCode;
                retAts.payInfoCode = tmpRespCode;
            } else if (ConnState.FAIL.equals(tmpStrRet[0])) {
                retAts.respCode = "0";
                retAts.respInfo = tmpStrRet[1];
                retAts.transState = PaymentState.FAIL_Batch;
                retAts.payInfoCode = FailCode.E9999;
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = tmpStrRet[1];
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.toString();
            WriteBankLogLn(ex);
        }

        retAts.writeRetToATS();
        return retAts;
    }

    /**
     * 批量代扣查询
     * <p>
     * 参考文档：平安银行银企直连-橙e收款接口V2.5.docx
     * 参考接口：3.6 橙e收款交易结果查询[4033]
     */
    public RetAtsQryBatPayRec d_9198_QryBatPay(ReqQryBatPayRec p_req9198) throws Exception {
        RetAtsQryBatPayRec retAts = new RetAtsQryBatPayRec(p_req9198.reqHeader);
        retAts.reqSeqID = p_req9198.reqBatchNO;

        try {
            PAB01Header bankHeader = new PAB01Header();
            bankHeader.trncode = "4033";
            bankHeader.fourZero = "0000";
            bankHeader.reqSeqNo = p_req9198.reqHeader.transSeqID;

            XmlTextWriter xmlWriter = new XmlTextWriter();
            xmlWriter.autoFormat = false;
            writeCommonHeader(xmlWriter);

            xmlWriter.writeStartElement("Result");
            xmlWriter.writeElementString("ThirdVoucher", p_req9198.reqBatchNO);
            xmlWriter.writeEndDocument();

            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString(), bankHeader);

            if (tmpStrRet[0].length() == 0) {
                byte[] retBytes = tmpStrRet[1].getBytes(getCharset());
                String tmpRetCode = new String(retBytes, 87, 6, getCharset()).trim();
                String tmpRetMsg = new String(retBytes, 94, 99, getCharset()).trim();
                tmpStrRet[1] = tmpStrRet[1].substring(tmpStrRet[1].indexOf("<"));

                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    if ("000000".equals(tmpRetCode)) {
                        retAts.respCode = "0";
                        retAts.respInfo = tmpRetMsg;

                        String tmpbatchSTT = tmpBkReader.getFirstText("/Result/BStt");
                        if ("20".equals(tmpbatchSTT)) {
                            while (tmpBkReader.read("/Result/list")) {
                                RetAtsBatPayRecDetail tmpRetDetail = new RetAtsBatPayRecDetail();

                                tmpRetDetail.postScript = tmpBkReader.readedXElement.getSingleText("SThirdVoucher");
                                tmpRetDetail.payAct = tmpBkReader.readedXElement.getSingleText("OppAccNo");
                                tmpRetDetail.payName = tmpBkReader.readedXElement.getSingleText("OppAccName");
                                tmpRetDetail.payAmount = tmpBkReader.readedXElement.getSingleText("Amount");
                                tmpRetDetail.result = StringHelper.joinNotEmpty("+", tmpbatchSTT, tmpBkReader.readedXElement.getSingleText("stt"));
                                tmpRetDetail.payInfoCode = tmpBkReader.readedXElement.getSingleText("errorCode");
                                tmpRetDetail.memo = tmpBkReader.readedXElement.getSingleText("sttInfo");

                                retAts.writeRetDetail(tmpRetDetail);
                            }
                        } else if ("30".equals(tmpbatchSTT)) { // 30：失败
                            retAts.respCode = "0";
                            retAts.respInfo = tmpRetMsg;
                            String tmpbatchInfo = tmpBkReader.getFirstText("/Result/BatchInfo");
                            if (StringHelper.hasAnyChar(tmpbatchInfo)) {
                                retAts.respInfo = tmpbatchInfo;
                                retAts.payInfoCode = tmpbatchInfo;
                            }
                            retAts.transState = StringHelper.joinNotEmpty("+", tmpRetCode, tmpbatchSTT);
                        } else { // 其他为银行受理成功处理中
                            retAts.respCode = "-1";
                            retAts.respInfo = tmpRetMsg;
                        }
                    } else {
                        // 超过30分钟没结果,则判定支付失败
                        if ("YQ9996".equals(tmpRetCode)) {
                            if (!canBeNotExist(p_req9198, retAts, 30)) {
                                retAts.writeAfterDetail();
                                return retAts;
                            }

                            retAts.respCode = "0";
                            retAts.respInfo = tmpRetMsg;
                            retAts.transState = tmpRetCode;
                            retAts.payInfoCode = tmpRetCode;
                        }

                        retAts.respCode = "-1";
                        retAts.respInfo = tmpRetMsg;
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpRetMsg;
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = tmpStrRet[1];
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        retAts.writeAfterDetail();
        return retAts;
    }
}
